#include "croututils.h"
#include <stddef.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>

int bubble_sort_int(int *base, size_t count)
{
    int ipos, iter, swap, swapped;

    for (ipos = 0; ipos < count-1; ipos++) {
	swapped = 0;
	for (iter = 0; iter < count-1-ipos; iter++) {
	    if (base[iter+1] < base[iter]) {
		swap = base[iter];
		base[iter] = base[iter+1];
		base[iter+1] = swap;

		swapped++;
	    }
	}

	if (swapped == 0) {
	    break;
	}
    }
}

bool bubble_sort(void *base, size_t nobj, size_t size, comparator cmp)
{
    if (base == NULL || cmp == NULL || nobj <= 1 || size < 1) {
	return false;
    }

    char *swap = NULL;
    swap = (char *)malloc(size);
    if (swap == NULL) {
	return false;
    }

    int ipos, iter, swapped;
    for (ipos = 0; ipos < nobj-1; ipos++) {
	/* record swapped times for this loop */
	swapped = 0;

	/* swap values */
	for (iter = 0; iter < nobj-1-ipos; iter++) {
	    if (cmp((char *)base+(iter+1)*size, (char *)base+iter*size) < 0) {
		memcpy(swap, (char *)base+iter*size, size);
		memcpy((char *)base+iter*size, (char *)base+(iter+1)*size, size);
		memcpy((char *)base+(iter+1)*size, swap, size);

		/* record swap one more time */
		swapped++;
	    }
	}

	/* check for swaps, if none, sorting done */
	if (swapped == 0) {
	    break;
	}
    }

    free(swap);
    return true;
}


#define LENGTH	20
int main(int argc, char **argv)
{
    int buffer[LENGTH];
    randarr_int(buffer, LENGTH);

    listarr_int(buffer, LENGTH);
    bubble_sort(buffer, LENGTH, sizeof(buffer[0]), compare_int);
    listarr_int(buffer, LENGTH);

    return 0;
}
